package com.xhwl.logistics.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.common.dto.cent.vehicle.SupplierConfigDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.enums.vehicle.*;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.pojo.cent.sdata.Project;
import com.xhwl.common.pojo.cent.vehicle.*;
import com.xhwl.common.query.cent.device.ProductAccessQuery;
import com.xhwl.common.query.cent.sdata.AccountQuery;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.common.query.cent.vehicle.OrderQuery;
import com.xhwl.common.query.cent.vehicle.TempParkFeeQuery;
import com.xhwl.common.vo.cent.vehicle.*;
import com.xhwl.logistics.bo.cent.VehicleIntegratedConfigBO;
import com.xhwl.logistics.dao.*;
import com.xhwl.logistics.dto.CarDTO;
import com.xhwl.logistics.dto.CarLotListDTO;
import com.xhwl.logistics.dto.CardInfoDTO;
import com.xhwl.logistics.dto.PlateNoInfoDTO;
import com.xhwl.logistics.enums.VehicleCodeEnum;
import com.xhwl.common.query.cent.vehicle.CarQuery;
import com.xhwl.logistics.enums.VehicleParkingLotHandlerEnum;
import com.xhwl.logistics.service.IWeChatPayService;
import com.xhwl.logistics.service.cent.IAccountService;
import com.xhwl.logistics.service.cent.IProductAccessCentService;
import com.xhwl.logistics.service.cent.IProjectService;
import com.xhwl.logistics.service.IVehcCarService;
import com.xhwl.logistics.service.cent.QueryDeviceService;
import com.xhwl.logistics.strategy.IVehicleParkingLotHandler;
import com.xhwl.logistics.strategy.InfoSyncSupplierStrategy;
import com.xhwl.logistics.strategy.context.InfoSyncSupplierStrategyContext;
import com.xhwl.logistics.util.DateFormatUtil;
import com.xhwl.logistics.util.StringUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;


import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Lu.Aaron
 * @since 2021-02-08
 */
//@Service
@Slf4j
public class VehcCarServiceImpl extends ServiceImpl<VehcCarDao, VehcCar> implements IVehcCarService {
    @Autowired
    private VehcCarDao vehcCarDao;
    @Autowired
    private IAccountService iAccountService;
    @Autowired
    private IProjectService iProjectService;
    @Autowired
    private VehcCardChargeRuleDao vehcCardChargeRuleDao;
    @Autowired
    private VehcAreaDao vehcAreaDao;
    @Autowired
    private VehcParkingLotDao vehcParkingLotDao;
    @Autowired
    private IProductAccessCentService productAccessCentService;
    @Autowired
    private InfoSyncSupplierStrategyContext infoSyncSupplierStrategyContext;
    @Autowired
    private VehcCarJoinCcruleDao vehcCarJoinCcruleDao;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private VehcPassageDao vehcPassageDao;
    @Autowired
    private IWeChatPayService weChatPayService;
    @Autowired
    private VehcPayRecordDao vehcPayRecordDao;
    @Autowired
    private QueryDeviceService queryDeviceService;
    @Autowired
    private ApplicationContext applicationContext;

    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson add(CarVO carVO, Account account, Short industryId) {
        log.info("登陆人账号：{}",account);
        Integer count = vehcCarDao.selectCount(new QueryWrapper<VehcCar>().eq("plate_number", carVO.getPlateNumber()).eq("project_id",carVO.getProjectId()));
        if (count>=1) {
            throw new BusinessException(VehicleCodeEnum.PLATE_NUMBER_EXISTED.description);
        }
        //先根据项目id和产品分类id查询供应商
        @NotNull(message = "项目id必传") Integer projectId = carVO.getProjectId();
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        String thirdId=null;
        if (!deviceProjSupplierCategories.isEmpty()) {
            DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
            JSONObject properties = productAccess.getProperties();
            //获取供应商配置信息
            SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
            //根据supplierId以及策略模式选取对应的接口实现类
            Integer supplierId = productAccess.getSupplierId();
            InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(ParkSupplierEnum.getParkSupplierEnum(supplierId));
            Integer cardChargeRuleId = carVO.getCardChargeRuleId();
            if (null!=cardChargeRuleId) {
                if (!cardChargeRuleId.equals(0)) {
                    //0代表无（不需要同步给厂商）
                    //代表有绑定卡类型，需同步到厂商
                    CarDTO carDTO = handleCarDtoParam(carVO,account, null);
                    try {
                        //将carDTO转成Map
                        HashMap<String, Object> hashMap = Arrays.stream(BeanUtils.getPropertyDescriptors(carDTO.getClass()))
                                .filter(itm -> !"class".equals(itm.getName()))
                                .collect(HashMap::new,
                                        (map, pd) -> map.put(pd.getName(), ReflectionUtils.invokeMethod(pd.getReadMethod(), carDTO)),
                                        HashMap::putAll);
                        Map map = infoSyncSupplierService.addCar(hashMap,supplierConfigDTO);
                        thirdId = String.valueOf(map.get("thirdId"));
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                    //如果是月卡，并且有传有效期则而外需要调用充值接口（产品规定第一次新增时科拓接口涉及的金额全部传0，个人觉得产品需要重新规划这一部分，换其他供应商不知可行否）
                    VehcCardChargeRule vehcCardChargeRule = vehcCardChargeRuleDao.selectById(cardChargeRuleId);
                    if (CardTypeEnum.MONTH.equals(vehcCardChargeRule.getCardType())||CardTypeEnum.FREE.equals(vehcCardChargeRule.getCardType())) {
                        //需要调用充值接口
                        Map<String, Object> map = new HashMap<>();
                        //查询必须参数
                        VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectById(carVO.getParkingLotId());
                        map.put("parkId",vehcParkingLot.getThirdParkId());
                        map.put("validFrom",DateFormatUtil.date2Str(carVO.getValidBeginTime(),"yyyy-MM-dd HH:mm:ss"));
                        map.put("validTo",DateFormatUtil.date2Str(carVO.getValidEndTime(),"yyyy-MM-dd HH:mm:ss"));
                        map.put("cardId",thirdId);
                        map.put("userId",account.getId());
                        map.put("userName",account.getName());
                        map.put("cardType",vehcCardChargeRule.getCardType().getDisplay());
                        map.put("orderNo",UUID.randomUUID().toString());
                        map.put("payChannel",1); //科拓枚举：1现金 4微信 5支付宝
                        map.put("chargeMethod",2);//充值方式,(0 钱(单位:分),1 月,2 天,3 小时,4次)
                        map.put("amount", 0);
                        map.put("freeNumber", 0);
                        map.put("chargeNumber",DateFormatUtil.getDiffDay(DateFormatUtil.date2Str(carVO.getValidBeginTime(),"yyyy-MM-dd HH:mm:ss"),DateFormatUtil.date2Str(carVO.getValidEndTime(),"yyyy-MM-dd HH:mm:ss")));
                        try {
                            infoSyncSupplierService.recharge(map,supplierConfigDTO);
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                    }
                }
            }
        }
        VehcCar vehcCar = new VehcCar();
        BeanUtils.copyProperties(carVO,vehcCar);
        vehcCar.setRegisterTime(new Date());
        vehcCar.setRegisterAccountId(account.getId());
        vehcCar.setThirdId(thirdId);
        //平台端新增车辆都是属于审核通过
        vehcCar.setStatus(CarStatusEnum.VERIFICATION_SUCCESS);
        vehcCarDao.insert(vehcCar);
        //更新车与卡类型绑定表
        if (!Objects.isNull(carVO.getCardChargeRuleId())) {
            CardTypeEnum cardType = carVO.getCardType();
            if (null==cardType) {
                throw new BusinessException("卡类型必传");
            }
            VehcCarJoinCcrule vehcCarJoinCcrule = new VehcCarJoinCcrule();
            vehcCarJoinCcrule.setCardType(cardType);
            vehcCarJoinCcrule.setCarId(vehcCar.getId());
            vehcCarJoinCcrule.setCardChargeRuleId(carVO.getCardChargeRuleId());
            vehcCarJoinCcrule.setValidBeginTime(carVO.getValidBeginTime());
            vehcCarJoinCcrule.setValidEndTime(carVO.getValidEndTime());
            if (CardTypeEnum.STORE.equals(cardType)) {
                //储值卡 新增时balance默认为0
                vehcCarJoinCcrule.setBalance(0);
            }
            vehcCarJoinCcruleDao.insert(vehcCarJoinCcrule);
        }

        return ResultJson.success();
    }

    private CarDTO handleCarDtoParam(CarVO carVO, Account account, HashMap<String, Object> extraMap) {
        Integer carLotListId=null;
        Integer plateNoInfoId=null;
        Integer cardId=null;
        if (null!=extraMap) {
             carLotListId = (Integer) extraMap.get("carLotListId");
             plateNoInfoId = (Integer) extraMap.get("plateNoInfoId");
             String cardIdStr = (String) extraMap.get("cardId");
             cardId=Integer.valueOf(cardIdStr);
        }
        CarDTO carDTO = new CarDTO();
        carDTO.setUserId(account.getId());
        carDTO.setUserName(account.getName());
        CardInfoDTO cardInfoDTO = new CardInfoDTO();
        cardInfoDTO.setCardId(cardId);
        cardInfoDTO.setCardName(carVO.getOwnerName()+"卡");
        cardInfoDTO.setTel(carVO.getOwnerPhone());
        cardInfoDTO.setUseName(carVO.getOwnerName());
        carDTO.setCardInfo(cardInfoDTO);
        CarLotListDTO carLotListDTO = new CarLotListDTO();
        carLotListDTO.setId(carLotListId);
        carLotListDTO.setLotName(carVO.getOwnerName()+"车位");
        carLotListDTO.setLotCount(1);
        carLotListDTO.setSequence(1);
        VehcCardChargeRule vehcCardChargeRule = vehcCardChargeRuleDao.selectById(carVO.getCardChargeRuleId());
        CardTypeEnum cardType = vehcCardChargeRule.getCardType();
        if (cardType.equals(CardTypeEnum.MONTH)) {
            carLotListDTO.setCarType(2);
        }else if(cardType.equals(CardTypeEnum.STORE)){
            carLotListDTO.setCarType(3);
        }else if(cardType.equals(CardTypeEnum.TEMPORARILY)){
            carLotListDTO.setCarType(0);
        }else if(cardType.equals(CardTypeEnum.FREE)){
            carLotListDTO.setCarType(1);//产品自己定义说明：（供应商VIP卡对应平台的免费卡）
        }
        VehcArea vehcArea = vehcAreaDao.selectById(vehcCardChargeRule.getAreaId());
        String thirdAreaId = vehcArea.getThirdAreaId();
        List<String> list = Arrays.asList(thirdAreaId.split("-"));
        carLotListDTO.setAreaId( list);
        List<CarLotListDTO> carLotListDTOS = new ArrayList<>();
        carLotListDTO.setBeginTime(DateFormatUtil.date2Str(carVO.getValidBeginTime(),"yyyy-MM-dd HH:mm:ss"));
        carLotListDTO.setEndTime(DateFormatUtil.date2Str(carVO.getValidEndTime(),"yyyy-MM-dd HH:mm:ss"));
        carLotListDTOS.add(carLotListDTO);
        carDTO.setCarLotList(carLotListDTOS);
        PlateNoInfoDTO plateNoInfoDTO = new PlateNoInfoDTO();
        plateNoInfoDTO.setId(plateNoInfoId);
        plateNoInfoDTO.setPlateNo(carVO.getPlateNumber());
        List<PlateNoInfoDTO> plateNoInfoDTOS = new ArrayList<>();
        plateNoInfoDTOS.add(plateNoInfoDTO);
        carDTO.setPlateNoInfo(plateNoInfoDTOS);
        VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectById(vehcArea.getParkingLotId());
        if (!Objects.isNull(vehcParkingLot)) {
            carDTO.setParkId(vehcParkingLot.getThirdParkId());
        }
        carDTO.setCardChargeRuleId(carVO.getCardChargeRuleId());
        return carDTO;
    }

    @Override
    public ResultJson edit(CarVO carVO, Short industryId, Account account) {
        log.info("登陆人账号：{}",account);
        Integer count = vehcCarDao.selectCount(new QueryWrapper<VehcCar>().eq("plate_number", carVO.getPlateNumber()).ne("id",carVO.getId()));
        if (count>=1) {
            throw new BusinessException(VehicleCodeEnum.PLATE_NUMBER_EXISTED.description);
        }
        //先根据项目id和产品分类id查询供应商
        @NotNull(message = "项目id必传") Integer projectId = carVO.getProjectId();
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        VehcCar vehcCar = vehcCarDao.selectById(carVO.getId());
        String thirdId=vehcCar.getThirdId();
        if (!deviceProjSupplierCategories.isEmpty()) {
            DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
            JSONObject properties = productAccess.getProperties();
            //获取供应商配置信息
            SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
            //根据supplierId以及策略模式选取对应的接口实现类
            Integer supplierId = productAccess.getSupplierId();
            InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(ParkSupplierEnum.getParkSupplierEnum(supplierId));
            //通过parkingLotId查找第三方对应的thirdParkId
            Integer parkingLotId = carVO.getParkingLotId();
            VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectById(parkingLotId);
            String thirdParkId = vehcParkingLot.getThirdParkId();
            //判断是否绑定卡/是否修改了卡,并判断是否需要同步信息到供应商
            Integer cardChargeRuleId = carVO.getCardChargeRuleId();
            if (!Objects.isNull(cardChargeRuleId)) {
                VehcCarJoinCcrule carJoinCcruleFromDB = vehcCarJoinCcruleDao.selectOne(new QueryWrapper<VehcCarJoinCcrule>().eq("car_id", carVO.getId()));
                if (cardChargeRuleId.equals(0)) {
                    //（1）0代表无（不需要同步给厂商）
                    if (!carJoinCcruleFromDB.getCardChargeRuleId().equals(cardChargeRuleId)) {
                        //若表中原本的cardChargeRuleId的值从非0改成0，则需要修改，并且删除原本厂商与该车绑定的数据
                        carJoinCcruleFromDB.setCardChargeRuleId(cardChargeRuleId);
                        vehcCarJoinCcruleDao.updateById(carJoinCcruleFromDB);
                        CarDTO carDTO = new CarDTO();
                        carDTO.setCardId(vehcCar.getThirdId());
                        try {
                            log.info("调用厂商删除接口：cardId{}",vehcCar.getThirdId());
                            Map<String, Object> hashMap = new HashMap<>();
                            hashMap.put("cardId",vehcCar.getThirdId());
                            hashMap.put("parkId",thirdParkId);
                            infoSyncSupplierService.delete(hashMap,supplierConfigDTO);
                            log.info("调用厂商删除接口成功：cardId{}",vehcCar.getThirdId());
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                    }
                }else{
                    //（2）非0,需要同步到厂商
                    if (!carJoinCcruleFromDB.getCardChargeRuleId().equals(cardChargeRuleId)) {
                        //修改的和原本的不一样
                        carJoinCcruleFromDB.setCardChargeRuleId(cardChargeRuleId);
                        carJoinCcruleFromDB.setValidBeginTime(carVO.getValidBeginTime());
                        carJoinCcruleFromDB.setValidEndTime(carVO.getValidEndTime());
                        vehcCarJoinCcruleDao.updateById(carJoinCcruleFromDB);
                        //通过车辆对应的第三方id查询供应商（科拓）对应车辆的信息
                        HashMap<String, Object> extraMap = new HashMap<>();
                        try {
                            Map<String, Object> carMap = new HashMap<>();
                            carMap.put("cardId",vehcCar.getThirdId());
                            carMap.put("parkId",thirdParkId);
                            Map resultMap = infoSyncSupplierService.queryCarInfo(carMap,supplierConfigDTO);
                            if (null!=resultMap) {
                                Object plateNoInfo = resultMap.get("plateNoInfo");
                                Object carLotList = resultMap.get("carLotList");

                                List<PlateNoInfoDTO> plateNoInfoDTOS = JSONObject.parseArray(plateNoInfo.toString(), PlateNoInfoDTO.class);
                                Integer id1 = plateNoInfoDTOS.get(0).getId();
                                List<CarLotListDTO> carLotListDTOS = JSONObject.parseArray(carLotList.toString(), CarLotListDTO.class);
                                Integer id2 = carLotListDTOS.get(0).getId();

                                extraMap.put("carLotListId",id2);
                                extraMap.put("plateNoInfoId",id1);
                            }
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                        extraMap.put("cardId",thirdId);
                        try {
                            CarDTO carDTOUpdate = handleCarDtoParam(carVO,account,extraMap);
                            //将carDTOUpdate转成Map
                            Map<String, Object> carDTOUpdateMap = Arrays.stream(BeanUtils.getPropertyDescriptors(carDTOUpdate.getClass()))
                                    .filter(itm -> !"class".equals(itm.getName()))
                                    .collect(HashMap::new,
                                            (map, pd) -> map.put(pd.getName(), ReflectionUtils.invokeMethod(pd.getReadMethod(), carDTOUpdate)),
                                            HashMap::putAll);
                            infoSyncSupplierService.update(carDTOUpdateMap,supplierConfigDTO);
                        } catch (BeansException e) {
                            log.error(e.getMessage());
                        }
                    }else{
                        //修改的和原本的一样
                        carJoinCcruleFromDB.setValidBeginTime(carVO.getValidBeginTime());
                        carJoinCcruleFromDB.setValidEndTime(carVO.getValidEndTime());
                        vehcCarJoinCcruleDao.updateById(carJoinCcruleFromDB);
                    }
                }
            }
        }
        //VehcCar vehcCar = new VehcCar();
        BeanUtils.copyProperties(carVO,vehcCar);
        vehcCarDao.updateById(vehcCar);
        //更新车与卡类型绑定表
        if (!Objects.isNull(carVO.getCardChargeRuleId())) {
            CardTypeEnum cardType = carVO.getCardType();
            if (null==cardType) {
                throw new BusinessException("卡类型必传");
            }
            VehcCarJoinCcrule vehcCarJoinCcrule = vehcCarJoinCcruleDao.selectOne(new QueryWrapper<VehcCarJoinCcrule>().eq("card_charge_rule_id", carVO.getCardChargeRuleId()).eq("car_id", carVO.getId()));
            vehcCarJoinCcrule.setCardType(cardType);
            vehcCarJoinCcrule.setCarId(vehcCar.getId());
            vehcCarJoinCcrule.setCardChargeRuleId(carVO.getCardChargeRuleId());
            vehcCarJoinCcrule.setValidBeginTime(carVO.getValidBeginTime());
            vehcCarJoinCcrule.setValidEndTime(carVO.getValidEndTime());
            vehcCarJoinCcruleDao.updateById(vehcCarJoinCcrule);
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson delete(Integer id, Short industryId) {
        VehcCar vehcCar = vehcCarDao.selectById(id);
        String thirdId = vehcCar.getThirdId();
        if (StringUtils.isNotBlank(thirdId)) {
            //先根据项目id和产品分类id查询供应商
            @NotNull(message = "项目id必传") Integer projectId = vehcCar.getProjectId();
            List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
            if (!deviceProjSupplierCategories.isEmpty()) {
                DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
                //根据supplierId以及策略模式选取对应的接口实现类
                Integer supplierId = productAccess.getSupplierId();
                JSONObject properties = productAccess.getProperties();
                //获取供应商配置信息
                SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
                InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(ParkSupplierEnum.getParkSupplierEnum(supplierId));
                VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectById(vehcCar.getParkingLotId());
                try {
                    log.info("调用厂商删除接口：cardId{}",vehcCar.getThirdId());
                    Map<String, Object> hashMap = new HashMap<>();
                    hashMap.put("cardId",vehcCar.getThirdId());
                    hashMap.put("parkId",vehcParkingLot.getThirdParkId());
                    infoSyncSupplierService.delete(hashMap, supplierConfigDTO);
                    log.info("调用厂商删除接口成功：cardId{}",vehcCar.getThirdId());
                } catch (Exception e) {
                    throw new BusinessException("厂商删除接口异常");
                }
                //删除vehc_car_join_ccrule与vehc_car对应的关联关系
                vehcCarJoinCcruleDao.delete(new QueryWrapper<VehcCarJoinCcrule>().eq("car_id",id));
            }
        }
        vehcCarDao.deleteById(id);
        return ResultJson.success();
    }

    @Override
    public ResultJson carPage(CarQuery carQuery) {
        QueryWrapper<VehcCar> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Integer> projectIds = carQuery.getProjectIds();
        Page<VehcCar> page = new Page<>();
        page.setSize(Long.valueOf(carQuery.getPageSize()));
        page.setCurrent(Long.valueOf(carQuery.getCurrent()));
        if (null==projectIds||projectIds.isEmpty()) {
            throw new BusinessException(VehicleCodeEnum.PROJECT_ID_LACK.description);
        }
        if (null!=projectIds&&!projectIds.isEmpty()) {
            wrapper.in("project_id",projectIds);
        }
        if (StringUtils.isNotBlank(carQuery.getPlateNumber())) {
            wrapper.like("plate_number",carQuery.getPlateNumber());
        }
        if (null!=carQuery.getOwnerAccountIds()&&carQuery.getOwnerAccountIds().isEmpty()) {
            //为空则是有经过手机号或车主姓名过滤的没有此人的结果，则返回空
            return ResultJson.success(page);
        }
        if (null!=carQuery.getOwnerAccountIds()&&!carQuery.getOwnerAccountIds().isEmpty()) {
            //
            wrapper.in("owner_account_id",carQuery.getOwnerAccountIds());
        }
        if (null!=carQuery.getType()) {
            wrapper.eq("type",carQuery.getType());
        }
        if (StringUtils.isNotBlank(carQuery.getOwnerName())) {
            //调用主数据查询该名称的账号ids
            AccountQuery accountQuery = new AccountQuery();
            accountQuery.setLikeName(carQuery.getOwnerName());
            List<Account> accountList = accountService.getAccountList(null, accountQuery);
            log.info("调用主数据查询该名称的账号ids，获取结果：{}",accountList);
            if (!accountList.isEmpty()) {
                List<Integer> ids = accountList.stream().map(a -> a.getId()).collect(Collectors.toList());
                wrapper.in("owner_account_id",ids);
            }
        }
        Page<VehcCar> carPage = vehcCarDao.selectPage(page, wrapper);
        log.info("查询到车辆信息 {}", JSONObject.toJSONString(carPage.getRecords()));
        List<VehcCar> records = page.getRecords();
        //查询项目名称
        Set<Integer> projectIdsSet = records.stream().map(r -> r.getProjectId()).collect(Collectors.toSet());
        List<Integer> list = new ArrayList<>(projectIdsSet);
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.withIdList(list);
        List<Project> projects = iProjectService.list(projectQuery, null);
        //查询登记人名字
        List<Integer> accountIds = records.stream().map(v -> v.getRegisterAccountId()).collect(Collectors.toList());
        List<Integer> ownerAccountIds = records.stream().map(v -> v.getOwnerAccountId()).collect(Collectors.toList());
        accountIds.addAll(ownerAccountIds);
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setIdList(accountIds);
        List<Account> accounts = iAccountService.getAccountList(null, accountQuery);
        records.forEach(r->{
            projects.forEach(project -> {
                if (r.getProjectId().equals(project.getId())) {
                    r.setProjectName(project.getName());
                }
            });
            accounts.forEach(account -> {
                if (r.getRegisterAccountId().equals(account.getId())) {
                    r.setRegisterAccountName(account.getName());
                }
                if (r.getOwnerAccountId().equals(account.getId())) {
                    r.setOwnerName(account.getName());
                    r.setOwnerPhone(account.getPhone());
                }
            });

        });
        return ResultJson.success(carPage);
    }
    @Override
    public List<Account> getAccountsByName(String name) {
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setLikeName(name);
        List<Account> accounts = iAccountService.getAccountList(null, accountQuery);
        return accounts;
    }

    @Override
    public ResultJson getRegisteredCar(CarQuery carQuery) {
        String plateNumber = carQuery.getPlateNumber();
        List<Integer> projectIds = carQuery.getProjectIds();
        QueryWrapper<VehcCar> wrapper = new QueryWrapper<VehcCar>();
        if (StringUtils.isNotBlank(plateNumber)) {
            wrapper.like("plate_number", plateNumber);
        }
        if (null!=projectIds&&!projectIds.isEmpty()) {
            wrapper.in("project_id", projectIds);
        }
        List<VehcCar> vehcCars = vehcCarDao.selectList(wrapper);
        return ResultJson.success(vehcCars);
    }

    @Override
    public ResultJson detail(Integer id) {
        VehcCar vehcCar = vehcCarDao.selectById(id);
        VehcCarJoinCcrule vehcCarJoinCcrule = vehcCarJoinCcruleDao.selectOne(new QueryWrapper<VehcCarJoinCcrule>().eq("car_id", id));
        Map<String, Object> map = new HashMap<>();
        String validBeginTimeStr =null;
        String validEndTimeStr =null;
        String name=null;
        CardTypeEnum cardType=null;
        Integer cardChargeRuleId =null;
        if (null!=vehcCarJoinCcrule) {
            Date validBeginTime = vehcCarJoinCcrule.getValidBeginTime();
            Date validEndTime = vehcCarJoinCcrule.getValidEndTime();
            validBeginTimeStr = DateFormatUtil.date2Str(validBeginTime, "yyyy-MM-dd HH:mm:ss");
            validEndTimeStr = DateFormatUtil.date2Str(validEndTime,"yyyy-MM-dd HH:mm:ss");
            VehcCardChargeRule vehcCardChargeRule = vehcCardChargeRuleDao.selectById(vehcCarJoinCcrule.getCardChargeRuleId());
            if (null!=vehcCardChargeRule) {
                name= vehcCardChargeRule.getName();
                cardType=vehcCardChargeRule.getCardType();
                cardChargeRuleId = vehcCarJoinCcrule.getCardChargeRuleId();
            } else {
                //fix bug：车辆编辑时，查询车辆的详情时，当新增车辆时没有绑定车卡，需要返回一个无车卡的信息给前端
                name= "无";
                cardType=CardTypeEnum.NO;
                cardChargeRuleId = 0;
                //fix bug：车辆编辑时，查询车辆的详情时，当新增车辆时没有绑定车卡，需要返回一个无车卡的信息给前端
            }
        }
        VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectById(vehcCar.getParkingLotId());
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.withId(vehcCar.getProjectId());
        log.info("查询主数据项目信息：{}",vehcCar.getProjectId());
        Project project = iProjectService.getOne(projectQuery, null);
        Account account = accountService.findById(vehcCar.getOwnerAccountId());
        map.put("projectName",project.getName());
        map.put("projectId",project.getId());
        map.put("parkingLotId",vehcCar.getParkingLotId());
        map.put("parkingLotName",vehcParkingLot.getName());
        map.put("plateNumber",vehcCar.getPlateNumber());
        map.put("type",vehcCar.getType());
        map.put("ownerAccountId",vehcCar.getOwnerAccountId());
        map.put("ownerName",account.getName());
        map.put("ownerPhone",account.getPhone());
        map.put("cardType",cardType);
        map.put("name",name);
        map.put("cardChargeRuleId",cardChargeRuleId);
        map.put("color",vehcCar.getColor());
        map.put("validBeginTime",validBeginTimeStr);
        map.put("validEndTime",validEndTimeStr);
        return ResultJson.success(map);
    }

    @Override
    public ResultJson addFromAPP(CarVO carVO, Account account, Short industryId) {

        if (account == null || account.getId() == null) {
            throw new BusinessException("请先完成登录");
        }
        log.info("登陆人账号：{}",account);
        //根据项目id查询第三方车场id
        @NotNull(message = "项目id必传") Integer projectId = carVO.getProjectId();
        String thirdParkId = getThirdParkId(industryId, projectId);
        VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectOne(new QueryWrapper<VehcParkingLot>().eq("third_park_id", thirdParkId));
        //根据thirdParkId查询对应的parkingLotId,设置parkingLotId
        carVO.setParkingLotId(vehcParkingLot.getId());
        //设置第三方车场id和车主账号id
        carVO.setThirdParkId(thirdParkId);
        carVO.setOwnerAccountId(account.getId());
        //判定车牌号是否重复
        Integer count = vehcCarDao.selectCount(new QueryWrapper<VehcCar>().eq("plate_number", carVO.getPlateNumber()).eq("project_id",projectId));
        if (count>=1) {
            throw new BusinessException("项目已存在该车牌号请联系管理处");
        }
        //新增车辆记录
        VehcCar vehcCar = new VehcCar();
        BeanUtils.copyProperties(carVO,vehcCar);
        vehcCar.setRegisterTime(new Date());
        vehcCar.setRegisterAccountId(account.getId());
        vehcCar.setStatus(CarStatusEnum.WITH_NO_VERIFICATION);
        vehcCarDao.insert(vehcCar);
        return ResultJson.success("添加成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson cardApply(ApplyCarCardVO applyCarCardVO) {
        VehcCardChargeRule vehcCardChargeRule = vehcCardChargeRuleDao.selectById(applyCarCardVO.getCardChargeRuleId());
        VehcCarJoinCcrule vehcCarJoinCcrule = new VehcCarJoinCcrule();
        vehcCarJoinCcrule.setCarId(applyCarCardVO.getCarId());
        vehcCarJoinCcrule.setCardChargeRuleId(applyCarCardVO.getCardChargeRuleId());
        vehcCarJoinCcrule.setCardType(vehcCardChargeRule.getCardType());
        if (CardTypeEnum.STORE.equals(vehcCardChargeRule.getCardType())) {
            vehcCarJoinCcrule.setBalance(0);
        }
        vehcCarJoinCcruleDao.insert(vehcCarJoinCcrule);
        //修改车辆状态未审核中
        VehcCar vehcCar = vehcCarDao.selectById(applyCarCardVO.getCarId());
        vehcCar.setStatus(CarStatusEnum.UNDER_VERIFICATION);
        vehcCarDao.updateById(vehcCar);
        return ResultJson.success("申请成功");
    }

    @Override
    public ResultJson manage(CarQuery carQuery, Account account, Short industryId) {
        log.info("入参：{},登陆人：{}",carQuery,account.getName());
        Integer current = carQuery.getCurrent();
        Integer pageSize = carQuery.getPageSize();
        if (account.getId() == null) {
            throw new BusinessException("请先完成登录");
        }
        CarAuthEnum carAuthEnum = carQuery.getCarAuthEnum();
        if (null==carAuthEnum) {
            throw new BusinessException("认证状态必传");
        }
        Integer projectId = carQuery.getProjectId();
        if (null==projectId) {
            throw new BusinessException("项目id必传");
        }
        //根据项目id查询第三方车场id
        String thirdParkId = getThirdParkId(industryId, projectId);
        VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectOne(new QueryWrapper<VehcParkingLot>().eq("third_park_id", thirdParkId));

        carQuery.setParkingLotId(vehcParkingLot.getId());
        List<Integer> carStatusEnums = new ArrayList<>();
        List<Integer> ownerAccountIds = new ArrayList<>();
        ownerAccountIds.add(account.getId());
        carQuery.setOwnerAccountIds(ownerAccountIds);
        if (CarAuthEnum.NO.equals(carAuthEnum)) {
            carStatusEnums.add(CarStatusEnum.WITH_NO_VERIFICATION.getType());
            carStatusEnums.add(CarStatusEnum.UNDER_VERIFICATION.getType());
            carStatusEnums.add(CarStatusEnum.VERIFICATION_FAIL.getType());
        }else if(CarAuthEnum.YES.equals(carAuthEnum)){
            carStatusEnums.add(CarStatusEnum.VERIFICATION_SUCCESS.getType());
        }
        carQuery.setCurrent((carQuery.getCurrent() - 1) * carQuery.getPageSize());
        carQuery.setCarStatusList(carStatusEnums);
        List<CarPageVO> list = vehcCarDao.queryCarList(carQuery);
        Long total = vehcCarDao.queryCarTotal(carQuery);
        //设置车场名称
        list.forEach(l->l.setParkingLotName(vehcParkingLot.getName()));
        //处理未认证和已认证之间的区域权限，通道权限显示问题
        if (CarAuthEnum.NO.equals(carAuthEnum)) {
            //未认证，areaId设置为null
            list.forEach(l->l.setAreaId(null));
        }else if(CarAuthEnum.YES.equals(carAuthEnum)){
            //已认证，根据areaId设置区域权限，通道权限显示问题
            List<Integer> areaIds = list.stream().map(CarPageVO::getAreaId).collect(Collectors.toList());
            //去除areaId为null的情况
            areaIds= areaIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
            log.info("区域ids:{}",areaIds);
            List<VehcArea> vehcAreas =new ArrayList<>();
            if (!areaIds.isEmpty()) {
                vehcAreas = vehcAreaDao.selectBatchIds(areaIds);

            }
            List<VehcArea> finalVehcAreas = vehcAreas;
            list.forEach(l->{

                if (null==l.getAreaId()) {
                    l.setAreaName("所有");
                    l.setPassageName("所有");
                }else{
                    finalVehcAreas.forEach(v->{
                        if (l.getAreaId().equals(v.getId())) {
                            l.setAreaName(v.getName());
                            l.setPassageName("所有");
                        }
                    });
                }
            });
        }
        Page<CarPageVO> page = new Page<>();
        page.setTotal(total);
        page.setCurrent(current);
        page.setSize(pageSize);
        page.setRecords(list);
        return ResultJson.success(page);
    }

    private String getThirdParkId(Short industryId, Integer projectId) {
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        if (deviceProjSupplierCategories.isEmpty()) {
            throw new BusinessException("该项目未配置供应商，请先配置");
        }
        DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
        JSONObject properties = productAccess.getProperties();
        if (null == properties) {
            throw new BusinessException("该项目未配置第三方车场id，请先在供应商管理平台配置");
        }
        return (String) properties.get("thirdParkId");
    }

    @Override
    public ResultJson resubmit(CarVO carVO, Account account, Short industryId) {
        Integer id = carVO.getId();
        if (null==id) {
            throw new BusinessException("车辆id必传");
        }
        @NotEmpty String plateNumber = carVO.getPlateNumber();
        @NotNull CarTypeEnum type = carVO.getType();
        String color = carVO.getColor();
        String carPicUrl = carVO.getCarPicUrl();
        VehcCar vehcCar = vehcCarDao.selectById(id);
        vehcCar.setPlateNumber(plateNumber);
        vehcCar.setType(type);
        vehcCar.setColor(color);
        vehcCar.setCarPicUrl(carPicUrl);
        vehcCarDao.updateById(vehcCar);
        return ResultJson.success("提交成功");
    }

    @Override
    public ResultJson tempParkFeeQuery(TempParkFeeQuery tempParkFeeQuery, Short industryId) {
        @NotNull(message = "项目id必传") Integer projectId = tempParkFeeQuery.getProjectId();
        @NotEmpty(message = "车牌号必传") String plateNumber = tempParkFeeQuery.getPlateNumber();
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        if (deviceProjSupplierCategories.isEmpty()) {
            throw new BusinessException("该项目未配置供应商，请先配置");
        }
        DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
        JSONObject properties = productAccess.getProperties();
        if (null == properties) {
            throw new BusinessException("该项目未配置第三方车场id，请先在供应商管理平台配置");
        }
        //获取供应商配置信息
        SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
        String thirdParkId = (String)properties.get("thirdParkId");
        //根据supplierId以及策略模式选取对应的接口实现类
        Integer supplierId = productAccess.getSupplierId();
        InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(ParkSupplierEnum.getParkSupplierEnum(supplierId));
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("plateNo",plateNumber);
        paramMap.put("parkId",thirdParkId);
        Map map = infoSyncSupplierService.tempParkFeeQuery(paramMap,supplierConfigDTO);
        if (null==map) {
            throw new BusinessException("该车牌无相关临停账单");
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("rechargeType",RechargeTypeEnum.TEMP_PARK_RECHARGE);
        resultMap.put("entranceTime",map.get("entryTime"));
        Integer elapsedTime = (Integer)map.get("elapsedTime");
        //分钟转化为秒
        elapsedTime=elapsedTime*60;
        resultMap.put("parkingContinuedTime",DateFormatUtil.getTime(elapsedTime));
        resultMap.put("amount", map.get("payable"));
        resultMap.put("orderNo",map.get("orderNo"));
        resultMap.put("plateNumber",map.get("plateNo"));
        return ResultJson.success(resultMap);
    }

    @Override
    public ResultJson unifiedOrder(CarPayVo carPayVo, Short industryId, Account account) {
        @NotNull PayTypeEnum payTypeEnum = carPayVo.getPayType();
        if (PayTypeEnum.WECHAT.equals(payTypeEnum)) {
            //调用微信统一下单
             return weChatPayService.unifiedOrder(carPayVo,account,industryId);
        }
        return  null;
    }

    @Override
    public ResultJson orderQuery(OrderQuery orderQuery, Short industryId) {
        @NotNull PayTypeEnum payTypeEnum = orderQuery.getPayTypeEnum();
        if (PayTypeEnum.WECHAT.equals(payTypeEnum)) {
            //调用微信统一下单
            return weChatPayService.orderQuery(orderQuery);
        }
        return null;
    }

    @Override
    @Async
    public ResultJson tempParkFeeRecharge(CarPayVo carPayVo, Short industryId) {
        @NotNull Integer projectId = carPayVo.getProjectId();
        @NotNull Integer amount = carPayVo.getAmount();
        String outTradeNo = carPayVo.getOutTradeNo();
        @NotNull PayTypeEnum payTypeEnum = carPayVo.getPayType();
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        if (deviceProjSupplierCategories.isEmpty()) {
            throw new BusinessException("该项目未配置供应商，请先配置");
        }
        DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
        JSONObject properties = productAccess.getProperties();
        if (null == properties) {
            throw new BusinessException("该项目未配置第三方车场id，请先在供应商管理平台配置");
        }
        //获取供应商配置信息
        SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
        String thirdParkId = (String)properties.get("thirdParkId");
        //根据supplierId以及策略模式选取对应的接口实现类
        Integer supplierId = productAccess.getSupplierId();
        InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(ParkSupplierEnum.getParkSupplierEnum(supplierId));
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("orderNo",outTradeNo);
        paramMap.put("parkId",thirdParkId);
        paramMap.put("amount",amount);
        //科拓付款方式，1现金 2银行卡 3电子现金 4微信 5支付宝 6城市E通卡
        //科拓收费终端，4微信平台 5APP（安卓/IOS）
        if (PayTypeEnum.WECHAT.equals(payTypeEnum)) {
            paramMap.put("payMethod",4);
            paramMap.put("payType",4 );
        }else if(PayTypeEnum.ALIPAY.equals(payTypeEnum)){
            paramMap.put("payMethod",5);
            paramMap.put("payType",5 );
        }
        try {
            infoSyncSupplierService.tempParkRecharge(paramMap,supplierConfigDTO);
            //记录缴费记录
            VehcPayRecord vehcPayRecord = new VehcPayRecord();
            BeanUtils.copyProperties(carPayVo,vehcPayRecord);

            //缴费记录实体类的改变，取消了该字段
//            vehcPayRecord.setRechargeType(carPayVo.getRechargeType());

            vehcPayRecord.setPayTime(DateFormatUtil.stringDate2Date(carPayVo.getTimeEnd()));
            vehcPayRecordDao.insert(vehcPayRecord);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return ResultJson.success();
    }

    @Override
    @Async
    @Transactional(rollbackFor = {Exception.class})
    public ResultJson storeCarRecharge(CarPayVo carPayVo, Short industryId) {
        @NotNull Integer projectId = carPayVo.getProjectId();
        @NotNull Integer amount = carPayVo.getAmount();
        String outTradeNo = carPayVo.getOutTradeNo();
        Integer carId = carPayVo.getCarId();
        String payer = carPayVo.getPayer();
        @NotNull PayTypeEnum payTypeEnum = carPayVo.getPayType();
        Integer payerAccountId = carPayVo.getPayerAccountId();
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        if (deviceProjSupplierCategories.isEmpty()) {
            throw new BusinessException("该项目未配置供应商，请先配置");
        }
        DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
        JSONObject properties = productAccess.getProperties();
        if (null == properties) {
            throw new BusinessException("该项目未配置第三方车场id，请先在供应商管理平台配置");
        }
        //获取供应商配置信息
        SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
        String thirdParkId = (String)properties.get("thirdParkId");
        //根据supplierId以及策略模式选取对应的接口实现类
        Integer supplierId = productAccess.getSupplierId();
        InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(ParkSupplierEnum.getParkSupplierEnum(supplierId));
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("orderNo",outTradeNo);
        paramMap.put("parkId",thirdParkId);
        paramMap.put("amount",amount);
        paramMap.put("cardType",CardTypeEnum.STORE.getDisplay());
        paramMap.put("userId",payerAccountId);
        paramMap.put("userName",payer);
        //科拓付款方式，1现金 2银行卡 3电子现金 4微信 5支付宝 6城市E通卡
        if (PayTypeEnum.WECHAT.equals(payTypeEnum)) {
            paramMap.put("payChannel",4) ;
        }else if(PayTypeEnum.ALIPAY.equals(payTypeEnum)){
            paramMap.put("payChannel",5) ;
        }
        //科拓系统充值方式,(0 钱(单位:分),1 月,2 天,3 小时,4次)
        paramMap.put("chargeMethod",0);
        //科拓系统充值车的充值月数或天数或次数或金额
        paramMap.put("chargeNumber",amount);
        paramMap.put("validFrom ",DateFormatUtil.date2Str(new Date(),"yyyy-MM-dd HH:mm:ss"));
        paramMap.put("validTo",DateFormatUtil.date2Str(new Date(),"yyyy-MM-dd HH:mm:ss"));
        paramMap.put("createTime",DateFormatUtil.date2Str(new Date(),"yyyy-MM-dd HH:mm:ss"));
        paramMap.put("remark","无");
        //查询carId对应的第三方id
        VehcCar vehcCar = vehcCarDao.selectById(carId);
        paramMap.put("cardId",Integer.valueOf(vehcCar.getThirdId()));
        try {
            infoSyncSupplierService.recharge(paramMap, supplierConfigDTO);
            //记录充值缴费记录
            VehcPayRecord vehcPayRecord = new VehcPayRecord();
            BeanUtils.copyProperties(carPayVo,vehcPayRecord);

            //缴费记录实体类的改变，取消了该字段
//            vehcPayRecord.setRechargeType(carPayVo.getRechargeType());

            vehcPayRecord.setPayTime(DateFormatUtil.stringDate2Date(carPayVo.getTimeEnd()));
            vehcPayRecordDao.insert(vehcPayRecord);
            //修改该储值车的余额
            VehcCarJoinCcrule vehcCarJoinCcrule = vehcCarJoinCcruleDao.selectOne(new QueryWrapper<VehcCarJoinCcrule>().eq("car_id", carId));
            Integer balance = vehcCarJoinCcrule.getBalance();
            vehcCarJoinCcrule.setBalance(Math.addExact(balance,amount));
            vehcCarJoinCcruleDao.updateById(vehcCarJoinCcrule);
            return ResultJson.success("充值成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultJson.fail(e.getMessage());
        }

    }

    @Override
    @Async
    @Transactional(rollbackFor = {Exception.class})
    public ResultJson monthCarRecharge(CarPayVo carPayVo, Short industryId) {

        @NotNull Integer projectId = carPayVo.getProjectId();
        @NotNull Integer amount = carPayVo.getAmount();
        String outTradeNo = carPayVo.getOutTradeNo();
        Integer carId = carPayVo.getCarId();
        String payer = carPayVo.getPayer();
        @NotNull PayTypeEnum payTypeEnum = carPayVo.getPayType();
        Integer payerAccountId = carPayVo.getPayerAccountId();
        Integer monthNum = carPayVo.getMonthNum();
        Date validBeginTime = carPayVo.getValidBeginTime();
        Date validEndTime = carPayVo.getValidEndTime();
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        if (deviceProjSupplierCategories.isEmpty()) {
            throw new BusinessException("该项目未配置供应商，请先配置");
        }
        DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
        JSONObject properties = productAccess.getProperties();
        //获取供应商配置信息
        SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
        if (null == properties) {
            throw new BusinessException("该项目未配置第三方车场id，请先在供应商管理平台配置");
        }
        String thirdParkId = (String)properties.get("thirdParkId");
        //根据supplierId以及策略模式选取对应的接口实现类
        Integer supplierId = productAccess.getSupplierId();
        InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(ParkSupplierEnum.getParkSupplierEnum(supplierId));
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("orderNo",outTradeNo);
        paramMap.put("parkId",thirdParkId);
        paramMap.put("amount",amount);
        paramMap.put("cardType",CardTypeEnum.STORE.getDisplay());
        paramMap.put("userId",payerAccountId);
        paramMap.put("userName",payer);
        //科拓付款方式，1现金 2银行卡 3电子现金 4微信 5支付宝 6城市E通卡
        if (PayTypeEnum.WECHAT.equals(payTypeEnum)) {
            paramMap.put("payChannel",4) ;
        }else if(PayTypeEnum.ALIPAY.equals(payTypeEnum)){
            paramMap.put("payChannel",5) ;
        }
        //科拓系统充值方式,(0 钱(单位:分),1 月,2 天,3 小时,4次)
        paramMap.put("chargeMethod",1);
        //科拓系统充值车的充值月数或天数或次数或金额
        paramMap.put("chargeNumber",monthNum);
        paramMap.put("validFrom ",validBeginTime);
        paramMap.put("validTo",validEndTime);
        paramMap.put("createTime",DateFormatUtil.date2Str(new Date(),"yyyy-MM-dd HH:mm:ss"));
        paramMap.put("remark","无");
        //查询carId对应的第三方id
        VehcCar vehcCar = vehcCarDao.selectById(carId);
        paramMap.put("cardId",Integer.valueOf(vehcCar.getThirdId()));
        try {
            infoSyncSupplierService.recharge(paramMap, supplierConfigDTO);
            //记录充值缴费记录
            VehcPayRecord vehcPayRecord = new VehcPayRecord();
            BeanUtils.copyProperties(carPayVo,vehcPayRecord);

            //缴费记录实体类的改变，取消了该字段
//            vehcPayRecord.setRechargeType(carPayVo.getRechargeType());

            vehcPayRecord.setPayTime(DateFormatUtil.stringDate2Date(carPayVo.getTimeEnd()));
            vehcPayRecordDao.insert(vehcPayRecord);
            //修改月卡有效期
            VehcCarJoinCcrule vehcCarJoinCcrule = vehcCarJoinCcruleDao.selectOne(new QueryWrapper<VehcCarJoinCcrule>().eq("car_id", carId));
            vehcCarJoinCcrule.setValidEndTime(validEndTime);
            vehcCarJoinCcruleDao.updateById(vehcCarJoinCcrule);
            return ResultJson.success("充值成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultJson.fail(e.getMessage());
        }
    }

    @Override
    public ResultJson mine(Account account) {
        if (account.getId() == null) {
            throw new BusinessException("请先完成登录");
        }
        List<VehcCar> vehcCars = vehcCarDao.selectList(new QueryWrapper<VehcCar>().eq("owner_account_id", account.getId()));
        return ResultJson.success(vehcCars);
    }

    /**
     * 用户预约车位
     */
    @Override
    public ResultJson<String> reserveSpace(CarVO carVO) {
        if(carVO.getProjectId()==null){
            throw new DataException("项目id为空");
        }
        //根据项目id获取集成配置信息
        VehicleIntegratedConfigBO vehicleIntegratedConfigBO = queryDeviceService.queryIntegratedConfigFromProjectId(carVO.getProjectId());
        IVehicleParkingLotHandler vehicleParkingLotHandler = applicationContext.getBean(VehicleParkingLotHandlerEnum.toVehicleParkingLotHandlerEnum(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProductId()).getHandlerName(),
                IVehicleParkingLotHandler.class);
        String orderNO = vehicleParkingLotHandler.reserverSpace(vehicleIntegratedConfigBO, carVO);
        return ResultJson.successWithResult(orderNO);
    }

    /**
     * 用户取消车位预约
     */
    @Override
    public ResultJson cancelReservice(String orderNo, Integer projectId) {
        if(StringUtils.isEmpty(orderNo)){
            throw new DataException("预约订单号为空!");
        }
        VehicleIntegratedConfigBO vehicleIntegratedConfigBO = queryDeviceService.queryIntegratedConfigFromProjectId(projectId);
        IVehicleParkingLotHandler vehicleParkingLotHandler = applicationContext.getBean(VehicleParkingLotHandlerEnum.toVehicleParkingLotHandlerEnum(
                vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProductId()).getHandlerName(), IVehicleParkingLotHandler.class);
        vehicleParkingLotHandler.cancelReserve(vehicleIntegratedConfigBO,orderNo);
        return ResultJson.successWithVoid();
    }

}
